package cn.jbolt.core.enjoy.directive;

import com.jfinal.kit.StrKit;
import com.jfinal.template.Directive;
import com.jfinal.template.Env;
import com.jfinal.template.expr.ast.Expr;
import com.jfinal.template.expr.ast.ExprList;
import com.jfinal.template.io.Writer;
import com.jfinal.template.stat.ParseException;
import com.jfinal.template.stat.Scope;

import java.io.IOException;

/**
 * 生成basemodel的时候解析type为长度或者fixed
 *
 * @ClassName: ColumnTypeToDirective
 * @author: JFinal学院-小木 QQ：909854136
 * @date: 2021年3月20日
 *
 */
public class ColumnTypeToDirective extends Directive {

	private Expr columnTypeExpr;
	private Expr changeToTypeExpr;
	private int paraNum;
	@Override
	public void setExprList(ExprList exprList) {
		this.paraNum = exprList.length();
		if (paraNum != 2) {
			throw new ParseException("Wrong number parameter of #columnTypeTo directive, need two parameters",
					location);
		}
		this.columnTypeExpr = exprList.getExpr(0);
		this.changeToTypeExpr = exprList.getExpr(1);
		if (this.columnTypeExpr == null || this.changeToTypeExpr == null) {
			throw new ParseException("Wrong number parameter of #columnTypeTo directive, need two parameters",
					location);
		}
	}
	@Override
	public void exec(Env env, Scope scope, Writer writer) {
		Object columnType = this.columnTypeExpr.eval(scope);
		Object changeToType = this.changeToTypeExpr.eval(scope);
		if (changeToType == null) {
			throw new ParseException("#columnTypeTo directive second param is empty. you can assign value:1 or 2",
					location);
		}
		String changeToTypeStr = changeToType.toString();
		int changeToTypeInt = Integer.parseInt(changeToTypeStr);
		if (columnType == null || StrKit.isBlank(columnType.toString())) {
			try {
				if (changeToTypeInt == 1) {
					// 查询长度
					writer.write("40");
				} else if (changeToTypeInt == 2) {
					// 查询fixed
					writer.write("0");
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			return;
		}
		String columnTypeStr = columnType.toString();
		try {
			if (changeToTypeInt == 1) {
				// 查询长度
				writer.write(getLength(columnTypeStr));
			} else if (changeToTypeInt == 2) {
				// 查询fixed
				writer.write(getFixed(columnTypeStr));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static String getFixed(String columnTypeStr) {
		int index = columnTypeStr.indexOf(",");
		if (index == -1) {
			return "0";
		}
		int lastIndex = columnTypeStr.lastIndexOf(")");
		String result = columnTypeStr.substring(index + 1, lastIndex);
		return StrKit.isBlank(result) ? "0" : result.trim();
	}

	public static String getLength(String columnTypeStr) {
		int index = columnTypeStr.indexOf("(");
		if (index == -1) {
			return getLenth2(columnTypeStr);
		}
		int lastIndex = columnTypeStr.lastIndexOf(")");
		String result = columnTypeStr.substring(index + 1, lastIndex);
		if (result.indexOf(",") == -1) {
			return result.trim();
		}
		if (result.trim().endsWith(",")) {
			return result.replace(",", "").trim();
		}
		String[] arr = result.trim().split(",");
		String len = arr[0].trim();
		if (StrKit.notBlank(len) && Integer.parseInt(len) == 0) {
			String type = columnTypeStr.substring(0, index);
			if (StrKit.isBlank(type)) {
				return "40";
			}
			return getLenth2(type);
		}
		return StrKit.isBlank(len) ? "40" : len;
	}

	private static String getLenth2(String type) {
		if (StrKit.isBlank(type)) {
			return "40";
		}
		type = type.trim().toLowerCase();
		if (type.indexOf("int") != -1 || type.indexOf("number") != -1 || type.indexOf("serial") != -1
				|| type.indexOf("decimal") != -1) {
			return "10";
		}
		if (type.indexOf("datetime") != -1 || type.indexOf("date") != -1 || type.indexOf("time") != -1) {
			return "20";
		}
		if (type.equalsIgnoreCase("char") || type.equalsIgnoreCase("bit")) {
			return "1";
		}
		if (type.indexOf("varchar") != -1 || type.indexOf("nchar") != -1) {
			return "255";
		}
		if (type.indexOf("blob") != -1 || type.indexOf("text") != -1) {
			return "3000";
		}
		return "40";
	}
}
